package xib.parserTools.data;

import java.util.ArrayList;
import xib.parserTools.interfaces.IHeaderData;
import xib.utils.EncodedString;
import xib.utils.XibDataException;


/**
 * Implementation from the interface IHeaderData, this implementation is
 * used to save the data from the source before to be processed by the core.
 * @author xavierds
 */
public final class HeaderData implements IHeaderData{

    /**
     * Field for the default language
     */
    private String defaultLanguage;

    /**
     * Field for the original language
     */
    private String originalLanguage;

    /**
     * List of avalaibles languages.
     */
    private ArrayList<String> availableLanguages;

    /**
     * Information about the titles.
     */
    private ArrayList<EncodedString> titles;

    /**
     * Information about the authors.
     */
    private ArrayList<ArrayList<EncodedString>> authors;

    /**
     * Default page height and width.
     */
    private int defaultPageHeight, defaultPageWidth;

    /**
     * Field who indicates if the panel was validate.
     */
    private boolean validate;

    /**
     * Default Constructor. It initializes the list of languages, authors and
     * titles. The other fields are initialized to null.
     */
    public HeaderData(){
        availableLanguages = new ArrayList<String>();
        authors = new ArrayList<ArrayList<EncodedString>>();
        titles = new ArrayList<EncodedString>();
        defaultLanguage = null;
        originalLanguage = "";
    }


    public String getDefaultLanguage() {
        if(defaultLanguage == null)
            throwXibDataException(new NullPointerException("Default " +
                    "language wasn't initialized properly."));
        return defaultLanguage;
    }


    public String getOriginalLanguage(){
        return originalLanguage;
    }


     public ArrayList<String> getAvailablesLanguages() {
        if(availableLanguages.size() == 0)
            throwXibDataException(new IllegalStateException("No avalaibles" +
                    "languages weren't defined properly."));
        return availableLanguages;
    }


    public ArrayList<EncodedString> getTitles() {
        if(titles.size() == 0)
            throwXibDataException(new IllegalStateException("No avalaibles" +
                    "titles weren't defined properly."));
        return titles;
    }


    public ArrayList<ArrayList<EncodedString>> getAuthors(){
        if(authors.size() == 0)
            throwXibDataException(new IllegalStateException("No avalaibles" +
                    "authors weren't defined properly."));
        return authors;
    }


    public int getDefaultPageHeight(){
        if(defaultPageHeight <= 0)
            throwXibDataException(new IllegalStateException("The default height" +
                    " wasn't defined properly."));
        return defaultPageHeight;
    }


    public int getDefaultPageWidth(){
        if(defaultPageWidth <= 0)
            throwXibDataException(new IllegalStateException("The default width" +
                    " wasn't defined properly."));
        return defaultPageWidth;
    }


    public void setDefaultLanguage(String language) {
        validate = false;
        if(language == null)
            throwXibDataException(new NullPointerException("The given language" +
                    " can not be null."));
        if(language.equals(""))
            throwXibDataException(new IllegalArgumentException("The given " +
                    "language can not the empty String."));
        this.defaultLanguage = language;
    }


    public void setOriginalLanguage(String language) {
        validate = false;
        if(language == null)
            throwXibDataException(new NullPointerException("The given language" +
                    " can not be null."));
        if(language.equals(""))
            throwXibDataException(new IllegalArgumentException("The given " +
                    "language can not the empty String."));
        this.originalLanguage = language;
    }


    public void addLanguage(String language) {
        validate = false;
        if(language == null)
            throwXibDataException(new NullPointerException("The given language" +
                    " can not be null."));
        if(language.equals(""))
            throwXibDataException(new IllegalArgumentException("The given " +
                    "language can not the empty String."));
        if(availableLanguages.contains(language))
            throwXibDataException(new IllegalArgumentException("The given " +
                    "language is already defined."));
        this.availableLanguages.add(language);
    }


    public void addAuthor(ArrayList<String> names, ArrayList<String> languages){
        validate = false;
        if(names == null || languages == null)
            throwXibDataException(new NullPointerException("The given languages" +
                    " or names can not be null."));
        if(names.size() != languages.size())
            throwXibDataException(new IllegalArgumentException("The given" +
                    "names and languages must be from the same size."));
        
        ArrayList<EncodedString> author = new ArrayList<EncodedString>();
        for(int i = 0; i < names.size(); i++){
                author.add(new EncodedString(names.get(i), languages.get(i)));
        }

        authors.add(author);
    }


    public void addTitle(String title, String language) {
        validate = false;
        if(title == null || language == null)
            throwXibDataException(new NullPointerException("The given language" +
                    " or title can not be null."));
        if(title.equals("") != language.equals(""))
            throwXibDataException(new IllegalArgumentException("The given" +
                    "language or title can not be the emtpy String."));
        titles.add(new EncodedString(title,language));
    }


    public void setDefaultPageHeightAndWidth(int width, int height) {
       validate = false;
       if(height <= 0 || width <= 0)
           throwXibDataException(new IllegalArgumentException("the given width" +
                   " and height must be greater than 0"));
       this.defaultPageWidth = width;
       this.defaultPageHeight = height;
    }

    
    public boolean validate() {
        if(!validate){
            if(defaultPageHeight <= 0 || defaultPageWidth <= 0)
                throwXibDataException(new IllegalStateException("The " +
                        "default page height or default page width must be " +
                        "initialized properly"));

            if(defaultLanguage == null)
                throwXibDataException(new NullPointerException("The " +
                        "default language wasn't initialized properly"));

            if(originalLanguage == null)
                throwXibDataException(new NullPointerException("The " +
                        "original language wasn't initialized properly"));

            if(availableLanguages.size() == 0)
                throwXibDataException(new IllegalStateException("The list of " +
                        "available languages wasn't initialized properly"));

            if(titles.size() == 0)
                throwXibDataException(new IllegalStateException("The " +
                        "list of titles wasn't initialized properly"));

            if(authors.size() == 0)
                throwXibDataException(new IllegalStateException("The " +
                        "list of authors wasn't initialized properly"));
            validate = true;
        }
        return true;
    }

    /**
     * Throw a new XibDataException with the cause from the given.
     * @param cause
     */
    private void throwXibDataException(Throwable cause){
        throw new XibDataException("Error in the internal data of the source, " +
                "in the ChapterData."
                , cause);
    }

}
